home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / dev / gui / textfield.lha / Textfield / Doc / textfield_gc.doc next >
Text File  |  1995-06-23  |  50KB  |  1,027 lines

  1. TABLE OF CONTENTS
  2.  
  3. textfield.gadget/Textfield.gadget
  4. textfield.gadget/Size_Issue
  5. textfield.gadget/Prog_Language
  6. textfield.gadget/Open_Library
  7. textfield.gadget/Class_Name
  8. textfield.gadget/OS_Version
  9. textfield.gadget/Str_Comparison
  10. textfield.gadget/Rendering
  11. textfield.gadget/Buffer_Access
  12. textfield.gadget/Buffer_Characters
  13. textfield.gadget/Changing_Attributes
  14. textfield.gadget/Move_or_Size
  15. textfield.gadget/Undo
  16. textfield.gadget/User_Docs
  17. textfield.gadget/Applicability
  18. textfield.gadget/Tags
  19. textfield.gadget/Borders
  20. textfield.gadget/Alignment
  21. textfield.gadget/Bugs
  22. textfield.gadget/Author
  23. textfield.gadget/GetClass()
  24. textfield.gadget/GetCopyright()
  25. textfield.gadget/Textfield.gadget           textfield.gadget/Textfield.gadget
  26.  
  27.     NAME
  28.         textfield.gadget -- multi-line text entry BOOPSI object (V3)
  29.  
  30.     LEGAL
  31.         textfield.gadget is Copyright © 1995 Mark Thomas
  32.         All rights reserved.
  33.  
  34.     FUNCTION
  35.         The textfield class allows you create an area on your screen for text
  36.         entry.  The class supports a number of features including unlimited
  37.         or limited size text entry, specifying the font and style to use,
  38.         specifying the colors for different parts (text, background, and
  39.         lines), two types of borders (with option to invert the borders for a
  40.         total of 4 types of borders) or no border, text left/center/right
  41.         justification, vertical centering, IntuiText labels, attached Images,
  42.         line spacing, limited character acceptance, insertion or block cursor,
  43.         cursor blinking speed or no blinking, read-only mode, modified buffer
  44.         flag, lined paper, cut/copy/paste/erase while editing or program-
  45.         matically, undo buffer, and settable word delimiter characters for
  46.         word wrapping.
  47. textfield.gadget/Size_Issue                       textfield.gadget/Size_Issue
  48.  
  49.     SIZE ISSUE
  50.  
  51.         The textfield class gadget should be used for relatively small areas
  52.         where you want to allow text entry.  Typically a size below 320 x 200
  53.         is a fairly reasonable limit, but larger sizes will work.  In other
  54.         words it is not intended to be a whole editor like Ed.  Please note
  55.         that the vertical size has more affect on speed than the horizontal
  56.         size.  Many people have ignored the size issue in previous versions,
  57.         and it doesn't seem to have caused problem.  I keep this here until
  58.         the day I can really optimize the gadget.
  59. textfield.gadget/Prog_Language                 textfield.gadget/Prog_Language
  60.  
  61.     PROGRAMMING LANGUAGE
  62.  
  63.         This gadget is written for a C language interface and is that way
  64.         simply because the Amiga development is geared more towards the C
  65.         language than any other.  This does not mean that the gadget cannot be
  66.         used with another language.  In particular, support for Oberon is
  67.         given in the form of two mod files.  One file, TextField.mod provides
  68.         the actual interface to the gadget class.  It can be compiled and
  69.         linked into an Oberon project.  The other, TestClass.mod is a sample
  70.         program, similar to the C version, that tests the class and shows how
  71.         to use the class.  Thanks goes to Stefan for taking the effort to
  72.         convert the files.
  73.  
  74.         If you use C, the important thing to know is that you need to include
  75.         the header file <gadgets/textfield.h>.  And depending on what you do
  76.         you may need to include some other files: <intuition/gadgetclass.h>,
  77.         <intuition/classes.h>, <intuition/classusr.h>, <intuition/icclass.h>,
  78.         <intuition/imageclass.h>, <utility/tagitem.h>.
  79. textfield.gadget/Open_Library                   textfield.gadget/Open_Library
  80.  
  81.     OPENING THE LIBRARY
  82.  
  83.         HOW TO OPEN THE TEXTFIELD GADGET LIBRARY (for non-SAS/C 6.50+ users)
  84.  
  85.         To use the class you must open the "textfield.gadget" library like so:
  86.         OpenLibrary("gadgets/textfield.gadget", 0).  If that was successful,
  87.         then you need to get the class pointer with the TEXTFIELD_GetClass()
  88.         function.  You do not have to check to make sure that the pointer
  89.         returned by TEXTFIELD_GetClass() is valid (see TEXTFIELD_GetClass
  90.         description).  You do not have to return the pointer with any
  91.         function, just do not use the pointer after you close the
  92.         "textfield.gadget" library.
  93.  
  94.         Here's a quick guide:
  95.  
  96.         struct Library *TextFieldBase;
  97.         Class *TextFieldClass;
  98.  
  99.         TextFieldBase = OpenLibrary("gadgets/textfield.gadget", 0)
  100.         if (TextFieldBase) {
  101.             TextFieldClass = TEXTFIELD_GetClass();
  102.  
  103.             /* use the class */
  104.  
  105.             TextFieldClass = NULL;
  106.             CloseLibrary(TextFieldBase);
  107.         }
  108.  
  109.  
  110.         HOW TO OPEN THE TEXTFIELD GADGET LIBRARY (for SAS/C 6.50+ users)
  111.  
  112.         If you use SAS/C 6.50 or greater, then you can use the TextFieldAuto.c
  113.         source file provided in the source draw to have the library open
  114.         automatically at startup, and close automatically at termination so
  115.         that you will not have to take care of these yourself.  I highly
  116.         recommend using this feature.  The file makes two variables available
  117.         to the client:
  118.  
  119.         extern struct Library *TextFieldBase;
  120.         extern Class *TextFieldClass;
  121.  
  122.         Starting in main() these varaibles will automatically be defined to
  123.         have the library base and the class pointer.  If the library fails to
  124.         open, SAS/C's auto-open feature will close down the program with a
  125.         standard Amiga requester telling the user what happened.
  126. textfield.gadget/Class_Name                       textfield.gadget/Class_Name
  127.  
  128.     NO PUBLIC CLASS NAME
  129.  
  130.         Future versions of the textfield.gadget intend to offer a public class
  131.         name that you can use, but that will have to wait until (or if)
  132.         Commodore or CATS return from the dead since I have to register the
  133.         class name.  At which time that a public class name is offered, both
  134.         the old TEXTFIELD_GetClass() and the class name can be used with the
  135.         NewObject() function so that old and new programs will work.
  136. textfield.gadget/OS_Version                       textfield.gadget/OS_Version
  137.  
  138.     WORKS ON OS 2.04 AND UP
  139.  
  140.         The class will work on OS 2.04 and up, but for OS 2.04 through 2.1
  141.         there is no standard place to put .gadget libraries, so on these
  142.         systems the gadget should be installed in a drawer named "Gadgets" in
  143.         the same directory of the program that uses it.  See the example
  144.         program on how to open the class.  For OS 3.0 and up, just install
  145.         the textfield.gadget file in "SYS:Classes/Gadgets" like normal.
  146. textfield.gadget/Str_Comparison               textfield.gadget/Str_Comparison
  147.  
  148.     COMPARISON TO STRING GADGET
  149.  
  150.         Unlike the Amiga's string gadget, you get a gadget up message from
  151.         this gadget when you hit the right mouse button, or either Amiga keys
  152.         and the right alt keys pressed together.
  153. textfield.gadget/Rendering                         textfield.gadget/Rendering
  154.  
  155.     GADGET GRAPHIC ELEMENTS SUPPORTED
  156.  
  157.         This gadget does support the GA_Image tag for rendering a linked list
  158.         of images attached to the gadget.  Borders structures are not
  159.         supported.  (Complain if you want it.)
  160.  
  161.         As of version 2.0 the gadget also supports GA_IntuiText also.  This
  162.         means this gadget will render a linked list of IntuiText structures.
  163.         Note that GA_Text and GA_LabelImage are not supported.  (Like above,
  164.         complain if you want it.)
  165.  
  166.         This may or may not help you, but the render order for the elements of
  167.         this gadget is as follows:
  168.  
  169.             Border           (if enabled)
  170.             Lines of text
  171.             Image            (from GA_Image)
  172.             IntuiText        (from GA_IntuiText)
  173.  
  174.         So, images do overwrite borders and the lines of text.  Also note that
  175.         the gadget will render at least one line of text, and at least one
  176.         character per line, so restrict the width and height if this is a
  177.         problem.
  178. textfield.gadget/Buffer_Access                 textfield.gadget/Buffer_Access
  179.  
  180.     IMPORTANT NOTES ON ACCESSING THE BUFFER
  181.  
  182.         You must follow these rules or bad things can happen.
  183.  
  184.         The buffer pointer returned by TEXTFIELD_Text with the get method is
  185.         read only.  You must not modify the buffer at any time.
  186.  
  187.         The buffer pointer returned by TEXTFIELD_Text with the get method is
  188.         valid between any of the following:
  189.  
  190.             OffGadget()
  191.              valid
  192.             OnGadget()
  193.  
  194.             GA_Disabled, TRUE
  195.              valid
  196.             Disabled, FALSE
  197.  
  198.             TEXTFIELD_ReadOnly, TRUE
  199.              valid
  200.             TEXTFIELD_ReadOnly, FALSE
  201.  
  202.         Anytime you are outside all of the above situations, the pointer is
  203.         invalid and is guaranteed to change.  In fact you will get a NULL
  204.         pointer if you are outside all of the above situations.
  205.  
  206.         The size of the buffer you have can be obtained by issuing a get
  207.         method of TEXTFIELD_Size on the gadget inside the above situations.
  208.         And if you get a size of 0, then you must not reference the pointer
  209.         that is returned because it is NULL.  Be very careful to never
  210.         reference past the size given.  The buffer is not NULL terminated.
  211.         In C, that's buffer[0] through buffer[size - 1].
  212. textfield.gadget/Buffer_Characters         textfield.gadget/Buffer_Characters
  213.  
  214.     CHARACTERS ALLOWED IN THE BUFFER
  215.  
  216.         Normally the textfield gadget only allows you to put printable
  217.         characters into its buffer.  The gadget itself will filter out the
  218.         non-printable characters, so that the buffer will only contain the
  219.         values 0x0a, 0x20 - 0x7f, and 0xa0 - 0xff.
  220.  
  221.         In addition, the 0x0d character is automatically converted to 0x0a for
  222.         you.  The buffer that is passed to the gadget is not changed in any
  223.         way.  The gadget will copy the characters into its own internal
  224.         buffer, making the changes along the way.
  225.  
  226.         If for some reason you need to have the other characters in your
  227.         buffer, you can set the attribute TEXTFIELD_NonPrintChars to TRUE and
  228.         then all but 0x0d will be allowed in the buffer.  As before, the 0x0d
  229.         character will be converted to 0x0a.
  230.  
  231.         When characters are passed to the gadget, either by the application or
  232.         by the user, only the characters listed above are allowed in.  You can
  233.         also make further restrictions with TEXTFIELD_AcceptChars and
  234.         TEXTFIELD_RejectChars.  See the tags section for specific details.
  235. textfield.gadget/Changing_Attributes     textfield.gadget/Changing_Attributes
  236.  
  237.     CHANGING ATTRIBUTES
  238.  
  239.         When setting attributes, the gadget will always render the changes,
  240.         except if the gadget's geometry is changed, in which case it will
  241.         return a non-zero value to let you know changes need to be rendered by
  242.         refreshing the gadget.
  243.  
  244.         A geometry change means that the gadget moves in the window.
  245.         Specifically the following attributes cause the geometry to change:
  246.  
  247.         GA_Top, GA_Left, GA_Width, GA_Height, GA_RelWidth, GA_RelHeight,
  248.         GA_RelBottom, GA_RelRight.
  249.  
  250.         Here's how to handle this inside an application.
  251.  
  252.         if (SetGadgetAttrs(gadget, window, requester, ...)) {
  253.                 /* gadget needs rendering */
  254.                 RefreshGList(gadget, window, requester, 1);
  255.         }
  256.  
  257.         Some of the attributes cause others to not work properly.  Do not get
  258.         discouraged.  This only applies when sending them in one OM_SET
  259.         method.  It is unavoidable in the current release, so if you are
  260.         seeing things not work right, or in particular if a later tag works
  261.         but a former one does not, then split the attributes among two calls.
  262.         The gadget is set up so that later tags have precedence over former
  263.         tags.  This particularly applies to attributes that change the cursor
  264.         position and scrolling (changing top and such).
  265. textfield.gadget/Move_or_Size                   textfield.gadget/Move_or_Size
  266.  
  267.     MOVING OR SIZING THE GADGET
  268.  
  269.         If you want to move the gadget or change its size you should take note
  270.         of the section above on changing attributes.  In addition, the source
  271.         file TestClass.c in the TestClass example shows how to move the gadget
  272.         or change its size.  You should clear out the old position, then set
  273.         the new position and size, and finally refresh the gadget.
  274. textfield.gadget/Undo                                   textfield.gadget/Undo
  275.  
  276.     UNDO
  277.  
  278.         The undo function is implemented as an alternate paste buffer.  In
  279.         certain situations list below text will be copied into an undo buffer.
  280.         When the undo command is issued, the text in that buffer is pasted to
  281.         the current cursor position.  It does not really undo anything, it
  282.         just saves otherwise lost text.  When the undo is actually performed,
  283.         the undo buffer becomes cleared so that you cannot undo the same text
  284.         multiple times.
  285.  
  286.         List of places where text is saved in the undo buffer:
  287.  
  288.         - If you hit BACKSPACE or DELETE while some text is marked, the marked
  289.           text is placed in the undo buffer before the text is deleted.
  290.  
  291.         - If you hit SHIFT BACKSPACE or DELETE, the text that is deleted is
  292.           placed in the undo buffer.
  293.  
  294.         - If you hit ALT BACKSPACE or DELETE, the word that is deleted is
  295.           placed in the undo buffer.
  296.  
  297.         - If you hit CTRL X, the line that is deleted is placed in the undo
  298.           buffer.
  299.  
  300.         - If you type a character while some text is marked, the marked text
  301.           is placed in the undo buffer before the text is delete.
  302.  
  303.         - When you perform a normal paste while text is marked, the marked
  304.           text is placed in the undo buffer before it is deleted and the paste
  305.           occurs.
  306.  
  307.         - If you perform an erase (RAMIGA E or programmatically), the whole
  308.           buffer is placed in the undo buffer before it is deleted.
  309. textfield.gadget/User_Docs                         textfield.gadget/User_Docs
  310.  
  311.     DOCS FOR USERS
  312.  
  313.         You can mark text for cutting, copying, and erasing by simply clicking
  314.         and dragging.  Hitting alphanumeric keys replaces the text that is
  315.         highlighted.  Hitting cursor keys moves you to the front or end of the
  316.         highlighted text.
  317.  
  318.         If your cursor is already somewhere in the textfield, you can hold the
  319.         SHIFT key and click to mark the text from the current cursor position
  320.         to the place where you clicked.
  321.  
  322.         And the last way to mark text is to double-click, which will mark the
  323.         word you clicked on.  If you didn't click on a word, but rather you
  324.         clicked on spaces, the whole block of spaces is marked.  And if you
  325.         clicked on word delimiters, the whole block of delimiters is marked.
  326.  
  327.         While you drag to scroll, the farther away from the gadget your mouse
  328.         pointer is, the faster the gadget will scroll.
  329.  
  330.         For key sequences, the Amiga Style Guide was followed.  Anywhere the
  331.         undo buffer is mentioned, the statement is only valid if the
  332.         UndoStream is supplied (see tag section below).
  333.  
  334.         Key Sequence              Function
  335.         ----------------------------------------------------------------------
  336.                TAB                Activate next gadget (if GA_TabCycle)
  337.  
  338.          SHIFT TAB                Activate previous gadget (if GA_TabCycle)
  339.  
  340.          SHIFT CURSOR UP          Move to the top line in the current page, or
  341.                                   scroll up one page if cursor is on top line
  342.  
  343.          SHIFT CURSOR DOWN        Move to the bottom line in the current page,
  344.                                   or scroll down one page if cursor is on top
  345.                                   line
  346.  
  347.           CTRL or
  348.          SHIFT CURSOR RIGHT       Move to the right end of the current line
  349.  
  350.           CTRL or
  351.          SHIFT CURSOR LEFT        Move to the left end of the current line
  352.  
  353.          SHIFT BACKSPACE          Delete all text to the left of cursor on the
  354.                                   current line
  355.  
  356.          SHIFT DELETE             Delete all text to the right of the cursor
  357.                                   on the current line (in block cursor mode
  358.                                   this also includes the highlighted
  359.                                   character)
  360.  
  361.           CTRL CURSOR UP          Move to the top line of the text
  362.  
  363.           CTRL CURSOR DOWN        Move to the bottom line of the text
  364.  
  365.            ALT CURSOR RIGHT       Move to the next word (using the delimiter
  366.                                   characters provided by the programmer)
  367.  
  368.            ALT CURSOR LEFT        Move to the previous word (using the
  369.                                   delimiter characters provided by the
  370.                                   programmer)
  371.  
  372.            ALT CURSOR UP          Move to first character in gadget
  373.  
  374.            ALT CURSOR DOWN        Move to last character in gadget
  375.  
  376.            ALT BACKSPACE          Deletes the word to the left of the cursor
  377.                                   starting at the current cursor position
  378.  
  379.            ALT DEL                Deletes the word to the right of the cursor
  380.                                   starting at the current cursor position
  381.  
  382.           CTRL X                  Deletes the whole line that the cursor is on
  383.  
  384.         RAMIGA [                  Switch to left justification
  385.                                   (if TEXTFIELD_UserAlign is set)
  386.  
  387.         RAMIGA \ or
  388.         RAMIGA =                  Switch to center justification
  389.                                   (if TEXTFIELD_UserAlign is set)
  390.  
  391.         RAMIGA ]                  Switch to right justification
  392.                                   (if TEXTFIELD_UserAlign is set)
  393.  
  394.         RAMIGA E                  Erase all text in gadget (saved in undo
  395.                                   buffer) (no read-only)
  396.  
  397.         RAMIGA V                  Paste text from clipboard to current cursor
  398.                                   position (no read-only)
  399.  
  400.         RAMIGA A                  Mark all text
  401.  
  402.         RAMIGA U                  Undeletes (pastes) the last block of text
  403.                                   marked, or recover from RAMIGA E
  404.                                   (no read-only)
  405.  
  406.         When text is highlighted the following keys have functions:
  407.  
  408.                BACKSPACE          Erase marked text (saved in undo buffer)
  409.  
  410.                DEL                Erase marked text (saved in undo buffer)
  411.  
  412.         RAMIGA X                  Cut marked text to clipboard (no read-only)
  413.  
  414.         RAMIGA C                  Copy marked text to clipboard
  415.  
  416.         RAMIGA V                  Replace marked text with text from
  417.                                   clipboard (save marked text in undo
  418.                                   buffer) (no read-only)
  419.  
  420.                (any text key)     Replace marked text with that character
  421.         ----------------------------------------------------------------------
  422. textfield.gadget/Applicability                 textfield.gadget/Applicability
  423.  
  424.     APPLICABILITY IN THE TAGS SECTION
  425.  
  426.         In the TAGS section there is a statement with each attribute called
  427.         applicability.  It consists of a letters inside parentheses, like
  428.         (ISGNU).  These are standard BOOPSI letters that tell you which
  429.         standard methods the attribute can be used.  Here's what the letters
  430.         refer to (see the BOOPSI reference in the RKRM: Libraries for further
  431.         information):
  432.  
  433.             I - OM_NEW     (initializable)
  434.             S - OM_SET     (settable)
  435.             G - OM_GET     (gettable)
  436.             N - OM_NOTIFY  (is passed in gadget's notify message)
  437.             U - OM_UPDATE  (updatable)
  438. textfield.gadget/Tags                                   textfield.gadget/Tags
  439.  
  440.     TAGS
  441.         GA_Left (WORD) -- Specifies the left edge of the gadget.
  442.  
  443.         GA_Top (WORD) -- Specified the top edge of the gadget.
  444.  
  445.         GA_Width (WORD) -- Specifies the width of the gadget.  If a border is
  446.                 chosen, it will be rednered within this value.
  447.  
  448.         GA_Height (WORD) -- Specifies the height of the gadget.  If a border
  449.                 is chosen, it will be rendered within this value.
  450.  
  451.         GA_RelRight (WORD) -- Specifies the gadget as being relative to the
  452.                 right border of whatever the gadget is attached to.  See the
  453.                 BOOPSI Class Reference.
  454.  
  455.         GA_RelBottom (WORD) -- Specifies the gadget as being relative to the
  456.                 bottom border of whatever the gadget is attached to.  See the
  457.                 BOOPSI Class Reference.
  458.  
  459.         GA_RelWidth (WORD) -- Specifies the gadget as being relative to the
  460.                 width of whatever it is attached to.  See the BOOPSI Class
  461.                 Reference.
  462.  
  463.         GA_RelHeight (WORD) -- Specifies the gadget as being relative to the
  464.                 height of whatever it is attached to.  See the BOOPSI Class
  465.                 Reference.
  466.  
  467.         GA_Image (struct Image *) -- Pass a pointer to a linked list of images
  468.                 and this class will render them relative to the gadget's upper
  469.                 left corner.  See rendering order above.
  470.  
  471.         GA_IntuiText (struct IntuiText *) -- Pass a pointer to a linked list
  472.                 of IntuiText structures and this class will render them
  473.                 relative to the gadget's upper left corner.  See rendering
  474.                 order above.  (V2)
  475.  
  476.         GA_Disabled (BOOL) -- TRUE disables the gadget, not allowing input,
  477.                 and FALSE enables the gadget for input.  When the gadget is
  478.                 disables, it usually is ghosted, see TEXTFIELD_NoGhost for
  479.                 other conditions.
  480.  
  481.         GA_TabCycle (BOOL) -- Turns on tab cycling.  See the BOOPSI Class
  482.                 Reference.
  483.  
  484.         TEXTFIELD_Text (char *) -- This set/replaces text.  NULL means no
  485.                 change.  To set the buffer empty pass "" (pointer to empty
  486.                 string, not a NULL pointer).  When you use it to get text see
  487.                 special conditions under IMPORTANT in the Buffer_Access
  488.                 section above.  The cursor position is reset to the beginning
  489.                 (0).  The pointer passed must be a pointer to a NULL
  490.                 terminated string of characters.  If you have read-only mode
  491.                 turned on with TEXTFIELD_ReadOnly, this attribute still works.
  492.                 The text is copied to an internal buffer.
  493.  
  494.                 Default for this tag is NULL.  Applicability is (ISG U).
  495.  
  496.         TEXTFIELD_InsertText (char *) -- This inserts text at current cursor
  497.                 position and move the cursor to the end of the inserted text.
  498.                 You must pass a NULL terminated pointer to characters.  If you
  499.                 have read only mode turned on with TEXTFIELD_ReadOnly, this
  500.                 attribute still works.
  501.  
  502.                 Applicability is ( S  U).
  503.  
  504.         TEXTFIELD_DeleteText (ULONG) -- This deletes the number of characters
  505.                 you pass in the data field, starting at the current cursor
  506.                 position.  This attribute works even if read only mode is
  507.                 turned on with TEXTFIELD_ReadOnly.
  508.  
  509.                 Applicability is ( S  U). (V2)
  510.  
  511.         TEXTFIELD_TextFont (struct TextFont *) -- Sets the font for the gadget
  512.                 to use.  Pass the object a pointer to a TextFont structure.
  513.                 This supersedes TEXTFIELD_TextAttr below.  Please do not close
  514.                 this font while the gadget is using it. :)  The default font
  515.                 is your screen's current font.
  516.  
  517.                 Default for this tag is NULL. Applicability is (IS  U).
  518.  
  519.         TEXTFIELD_TextAttr (struct TextAttr *) -- Sets the font the gadget is
  520.                 to use.  Pass the gadget a pointer to a TextAttr structure.
  521.                 This is superseded by TEXTFIELD_TextFont.  The default font is
  522.                 the screen's current font.
  523.  
  524.                 Default for this tag is NULL.  Applicability is (IS  U).
  525.  
  526.         TEXTFIELD_FontStyle (ULONG) -- The style will get set to what you pass
  527.                 here.  The font style automatically gets reset when
  528.                 TEXTFIELD_TextFont or TEXTFIELD_TextAttr is set.
  529.  
  530.                 Default for this tag is FSF_PLAIN.  Applicability is (IS  U).
  531.  
  532.         TEXTFIELD_Delimiters (char *) -- You get the default if you pass NULL.
  533.                 Words break after these and "\n".  You will probably want at
  534.                 least " ", the space.  This string is not copied, so do not
  535.                 get rid of it while the gadget is in use.
  536.  
  537.                 Default for this tag is ",)!@^&*_=+\\|<>?/ ".  Applicability
  538.                 is (IS  U).
  539.  
  540.         TEXTFIELD_AcceptChars (char *) -- Tells the textfield gadget which
  541.                 characters to accept.  All others are rejected, and non-
  542.                 printable characters are automaically rejected.  Some of these
  543.                 characters may not be accepted if they also appear in the
  544.                 reject string.  This string is not copied, so do not get rid
  545.                 of it while the gadget is in use.  A NULL means to accept all
  546.                 characters.
  547.  
  548.                 Default for this tag is NULL.  Applicability is (IS  U). (V2)
  549.  
  550.         TEXTFIELD_RejectChars (char *) -- Tells the textfield gadget which
  551.                 characters to reject.  Non-printable characters are
  552.                 automaically rejected.  Characters specified with this are
  553.                 always rejected.  This string is not copied, so do not get rid
  554.                 of it while the gadget is in use.  A NULL means to reject no
  555.                 characters.
  556.  
  557.                 Default for this tag is NULL.  Applicability is (IS  U). (V2)
  558.  
  559.         TEXTFIELD_BlinkRate (ULONG) -- This sets the number of microseconds
  560.                 between a cursor on-off, or off-on transition.  A value of 0
  561.                 means do not blink.  Realistically, this should be set to
  562.                 100000 or higher since BOOPSI objects don't get idle messages
  563.                 any faster than about once every 10th of a second, but any
  564.                 value between 0 and 100000 will just make the cursor blink as
  565.                 fast as it can.  If you give the user an option of blink
  566.                 speed, suggest values: 0 for no blink, 750000 for a slow
  567.                 blink, 500000 for a medium blink, and 250000 for a fast blink.
  568.  
  569.                 Default for this tag is 0.  Applicability is (IS  U).
  570.  
  571.         TEXTFIELD_BlockCursor (BOOL) -- Turn on/off block cursor mode.  You
  572.                 should not use a block cursor if your font is italic because
  573.                 it looks weird.
  574.  
  575.                 Default for this tag is FALSE.  Applicability is (IS  U).
  576.  
  577.         TEXTFIELD_CursorPos (ULONG/ULONG *) -- Get/Set the cursor position.
  578.                 The cursor position returned is always an exact offset into
  579.                 the buffer you get to read via TEXTFIELD_Text.  0 takes you
  580.                 to the first character in the gadget, and 0xFFFFFFFF takes
  581.                 you past the last character in the gadget.  In general, any
  582.                 value you pass that is larger than what's returned by
  583.                 TEXTFIELD_Size will end up just past the last character in
  584.                 the gadget.  Setting this attribute will scroll the text to
  585.                 the position you set the cursor to.  If there is any text
  586.                 highlighted, highlighting is turned off.  When you get the
  587.                 current cursor position, you must pass a pointer to a ULONG.
  588.                 The ULONG will then have the cursor position in it.
  589.  
  590.                 Applicability is (ISG U).
  591.  
  592.         TEXTFIELD_Size (ULONG *) -- Returns the number of characters in the
  593.                 gadget's buffer, including \n characters.  This gives you the
  594.                 size when you want to use TEXTFIELD_Text to read the text in
  595.                 the gadget.  You must pass a pointer to a ULONG and then the
  596.                 ULONG will contain the value.
  597.  
  598.                 Applicability is (  G  ).
  599.  
  600.         TEXTFIELD_MaxSize (ULONG) -- Limit the size of text entered into the
  601.                 gadget.  0 means unlimited, otherwise limits the buffer size
  602.                 to what you pass.  This includes \n characters.
  603.  
  604.                 Default for this tag is UNLIMITED.  Applicability is (I    ).
  605.  
  606.         TEXTFIELD_MaxSizeBeep (BOOL) -- This attribute lets you set whether
  607.                 the system DisplayBeep() function is called if the user
  608.                 attempts to enter text into the gadget and the gadget is full
  609.                 (i.e. the gadget's buffer size is equal to the limit set by
  610.                 TEXTFIELD_MaxSize).  If TRUE the system beep is called.  If
  611.                 FALSE, the system beep is not called.
  612.  
  613.                 Default for this tag is TRUE.  Applicability is (IS  U). (V2)
  614.  
  615.         TEXTFIELD_Visible (ULONG *) -- Get the current number of visible
  616.                 lines.  It always returns how many _could_ be displayed if
  617.                 there were enough characters to fill the display.  Use for
  618.                 notifying a BOOPSI prop gadget.  You actually pass a pointer
  619.                 to a ULONG and then the ULONG will contain the value.  See
  620.                 example program.
  621.  
  622.                 Applicability is (  GN ).
  623.  
  624.         TEXTFIELD_Lines (ULONG *) -- Get the total number of lines in the
  625.                 buffer of the gadget.  Use this to also notify a BOOPSI prop
  626.                 gadget.  You pass a pointer to a ULONG and then the ULONG will
  627.                 contain the value.  See example program.
  628.  
  629.                 Applicability is (  GN ).
  630.  
  631.         TEXTFIELD_Top (ULONG/ULONG *) -- Get or set ordinal value of the top
  632.                 line.  0 is the top most line.  This is useful for ICA_MAP and
  633.                 ICA_TARGET when using the BOOPSI prop gadget and notifications.
  634.                 When you get the value you pass a pointer to a ULONG and then
  635.                 the ULONG will contain the value.  See sample program for
  636.                 example.
  637.  
  638.                 Default for this tag is 0.  Applicability is ( SGNU).
  639.  
  640.         TEXTFIELD_Partial (BOOL) -- When this flag is set to TRUE, partial
  641.                 lines will be shown at the bottom of the gadget.  When this
  642.                 flag is set to false, then only whole lines will be shown in
  643.                 the gadget.  Note that having both TEXTFIELD_VCenter, and
  644.                 TEXTFIELD_Partial on is not allowed and doesn't make sense.
  645.                 If both TEXTFIELD_VCenter and TEXTFIELD_Partial are turned on
  646.                 at the same time, only TEXTFIELD_VCenter will get turned on.
  647.  
  648.                 Default for this tag is FALSE.  Applicability is (IS  U).
  649.  
  650.         TEXTFIELD_NoGhost (BOOL) -- If TRUE, never ghost when gadget is
  651.                 disabled.  If FALSE, then ghost when gadget is disabled.  You
  652.                 can use this to make a read only multiline string gadget.  It
  653.                 has a special purpose, though.
  654.  
  655.                 Normally you will want a gadget to be enabled when allowing
  656.                 text to be entered.  However, when you need to read the text
  657.                 from the gadget, you have to disable it.  But disabling a
  658.                 gadget ghosts it.  So, with this option, you can pass
  659.                 GA_Disabled, TRUE, TEXTFIELD_NoGhost, TRUE at the same time
  660.                 and it will disable without ever showing the ghosted pattern.
  661.                 And likewise, passing the attributes GA_Disabled, FALSE,
  662.                 TEXTFIELD_NoGhost, FALSE will seamlessly reenable the gadget.
  663.                 While the gadget is disabled, read the text and then be on
  664.                 your way.  Also note that most S and U attributes are settable
  665.                 while the gadget is disabled, notably TEXTFIELD_Top.  This
  666.                 allows you to make a scrollable read-only multiline non-
  667.                 ghosted text, image capable, and border capable gadget.
  668.                 Sounds useful to me!
  669.  
  670.                 The read only mode is probably better.  See below.
  671.  
  672.                 Default for this tag is FALSE.  Applicability is (IS  U).
  673.  
  674.         TEXTFIELD_ReadOnly (BOOL) -- If TRUE, then the gadget does not allow
  675.                 text to be entered or deleted by the user.  However, the user
  676.                 can still highlight so that text can be copied to the
  677.                 clipboard.  If FALSE, then the gadget acts normally.  If you
  678.                 want a read only mode without clipboard support, then use the
  679.                 GA_Disabled and TEXTFIELD_NoGhost mode mentioned in the
  680.                 TEXTFIELD_NoGhost description.
  681.  
  682.                 All but two of the normal keyboard editing commands are
  683.                 ignored while in read-only mode.  RAMIGA-a highlights all
  684.                 text, and RAMIGA-c copies highlighted text to the clipboard.
  685.                 Other RAMIGA keys will get passed is TEXTFIELD_PassCommand is
  686.                 turned on.
  687.  
  688.                 So that the gadget acts more like it's not active while in
  689.                 this mode, certain keys events get passed on to the window:
  690.                 F1-F10, Help, Cursor keys.
  691.  
  692.                 Note that non-RAWKEY events, like mouse moves, buttons, and
  693.                 timer events are not passed on so that normal highlighting and
  694.                 scrolling can occur.
  695.  
  696.                 There is no visual change in the gadget when it is read-only
  697.                 other than it does not have a cursor.  You should set the
  698.                 border to an inverted bevel or inverted double-bevel.  By the
  699.                 style guide, inverted borders represent read-only gadgets.
  700.  
  701.                 Default for this tag is FALSE.  Applicability is (IS  U).
  702.                 (V2)
  703.  
  704.         TEXTFIELD_Modified (BOOL) -- This attribute is a flag that you can
  705.                 set and read to find out if a gadget's buffer has been
  706.                 modified in some way.  For instance, if you wanted to load
  707.                 some text into the gadget, then when the program quits
  708.                 determine if the text was modified then you would load and
  709.                 set the flag like this: TEXTFIELD_Text, text,
  710.                 TEXTFIELD_Modified, FALSE.  Note that the order matters, such
  711.                 that if they were reversed the text change would promptly
  712.                 set the modified flag to TRUE.  You can read or set this flag
  713.                 at any time.  The flag also notifies any listeners.
  714.  
  715.                 Default for this tag is FALSE.  Applicability is (ISGNU).
  716.                 (V2)
  717.  
  718.         TEXTFIELD_PassCommand (BOOL) -- This attribute is a flag to allow the
  719.                 gadget to pass unused right Amiga key sequences (command key
  720.                 sequences) on to the client application.  If the flag is set
  721.                 to TRUE then the key sequences are passed to the client.
  722.                 There is a side effect that causes the gadget to become
  723.                 inactive (as if the user had clicked outside the gadget).
  724.                 The default behavior (set to FALSE) is to ignore these key
  725.                 sequences so that the gadget remains active.
  726.  
  727.                 Default for this tag is FALSE.  Applicability is (IS  U).
  728.                 (V2)
  729.  
  730.         TEXTFIELD_NonPrintChars (BOOL) -- This attribute is a flag that when
  731.                 set to TRUE allows all characters except 0x0d into the
  732.                 gadget's buffer.  When the flag is set to FALSE, only
  733.                 printable characters are allowed in the buffer (0x20 - 0x7f,
  734.                 0xa0 - 0xff, and 0x0a).
  735.  
  736.                 Default for this tag is FALSE.  Applicability is (IS  U).
  737.                 (V3).
  738.  
  739.         TEXTFIELD_Border (ULONG) -- Sets the border type.  See defines below.
  740.                 The gadget offers a standard bevel, and standard double bevel.
  741.                 If you need another type, your could always create an image,
  742.                 link it to the gadget with GA_Image, and set its top and left
  743.                 edges above and to the left of this gadget (negative in the
  744.                 image structure), and make the width and height larger than
  745.                 this gadget.
  746.  
  747.                 Default for this tag is TEXTFIELD_BORDER_NONE.  Applicability
  748.                 is (IS  U).
  749.  
  750.         TEXTFIELD_Inverted (BOOL) -- If this flags is TRUE, the border is
  751.                 drawn inverted, if there is a border.  If FALSE, the border is
  752.                 drawn non-inverted.  This option is here in case you want to
  753.                 give the textfield gadget a read-only look when used in
  754.                 conjunction with TEXTFIELD_NoGhost and GA_Disabled.
  755.  
  756.                 Default for this tag is FALSE.  Applicability is (IS  U).
  757.  
  758.         TEXTFIELD_Up (ULONG) -- Moves the text up by one line.  You can pass
  759.                 anything, but it will only move the text up by a line, if it's
  760.                 not at the top already.  Useful BOOPSI notifications.
  761.  
  762.                 Applicability is ( S  U).
  763.  
  764.         TEXTFIELD_Down (ULONG) -- Moves the text down by one line.  You can
  765.                 pass anything, but it will only move the text down by a line,
  766.                 if it's not at the bottom already.  Useful for BOOPSI
  767.                 notifications.
  768.  
  769.                 Applicability is ( S  U).
  770.  
  771.         TEXTFIELD_Alignment (ULONG/ULONG *) -- Set/Get the line justification.
  772.                 This gadget offers left, center, and right justification.
  773.                 When you are getting the flags, you need to pass a pointer to
  774.                 a ULONG and then the ULONG will contain the flags.  See
  775.                 defines below.
  776.  
  777.                 Default for this tag is TEXTFIELD_ALIGN_LEFT.  Applicability
  778.                 is (ISG U).
  779.  
  780.         TEXTFIELD_VCenter (BOOL) -- Turn on/off vertical centering.  When on,
  781.                 the lines in the display are centered vertically.  If the
  782.                 total number of lines is less than the visible number of lines
  783.                 then the smaller number of lines are centered.  This allows
  784.                 you to center single lines of text within the gadget very
  785.                 easily.  For normal text entry operation, it is best to leave
  786.                 this off.  Also, check TEXTFIELD_Partial for possible
  787.                 conflicts when used with TEXTFIELD_VCenter.
  788.  
  789.                 Default for this tag is FALSE.  Applicability is (IS  U).
  790.  
  791.         TEXTFIELD_UserAlign (BOOL) -- If this is set at creation, then the
  792.                 user will have control over the left/center/right
  793.                 justification of text through RIGHT-AMIGA [, =, ] keyboard
  794.                 shortcuts.  If you want to save what the user has set the
  795.                 justification to, then do a GetAttr() on TEXTFIELD_Alignment.
  796.  
  797.                 Default for this tag is FALSE.  Applicability is (I    ).
  798.  
  799.         TEXTFIELD_RuledPaper (BOOL) -- Lets you set whether the paper
  800.                 (background) has ruled horizontal lines under each line of
  801.                 text or not.
  802.  
  803.                 Default for this tag is FALSE.  Applicability is (IS  U).
  804.  
  805.         TEXTFIELD_PaperPen (ULONG) -- This lets you specify the pen used for
  806.                 drawing the paper (background) of the gadget.  A value of -1
  807.                 means use default, which is BACKGROUNDPEN.
  808.  
  809.                 Default for this tag is -1.  Applicability is (IS  U).
  810.  
  811.         TEXTFIELD_InkPen (ULONG) -- This lets you specify the pen used for
  812.                 drawing the text.  A value of -1 means use the default, which
  813.                 is TEXTPEN.  If this pen, and the TEXTFIELD_LinePen are
  814.                 different, then rendering speed is slowed down a bit.  It is
  815.                 recommended that the line pen be left to -1.
  816.  
  817.                 Default for this tag is -1.  Applicability is (IS  U).
  818.  
  819.         TEXTFIELD_LinePen (ULONG) -- This lets you specify the pen used for
  820.                 drawing the ruled lines, if TEXTFIELD_RuledPaper is TRUE.  See
  821.                 TEXTFIELD_InkPen for possible speed problems when specifying
  822.                 this pen.  A value of -1 means to use the same pen as
  823.                 TEXTFIELD_InkPen.
  824.  
  825.                 Default for this tag is -1.  Applicability is (IS  U).
  826.  
  827.         TEXTFIELD_Spacing (UBYTE) -- Lets you set an extra amount of spacing
  828.                 between lines of text, for maybe doing 1-1/2 or double
  829.                 spacing.  It's a pixel value between 0 and 255.  The space is
  830.                 added to the top of each line.  In other words, the baseline
  831.                 is moved down by the amount you specify.
  832.  
  833.                 Default for this tag is 0.  Applicability is (IS  U).
  834.  
  835.         TEXTFIELD_TabSpaces (UBYTE) -- Lets you set how many spaces get
  836.                 inserted when the TAB key is pressed.  This does not work at
  837.                 all unless GA_TabCycle is set to FALSE.  In other words, if
  838.                 you have GA_TabCycle on, then you cannot have tabs insert
  839.                 any spaces.
  840.  
  841.                 Default for this tag is 0.  Applicability is (IS  U).
  842.                 (V3)
  843.  
  844.         TEXTFIELD_ClipStream (struct ClipboardHandle *) -- This tag allows
  845.                 clipboard support in the gadget.  Pass the pointer returned
  846.                 from the iffparse.library OpenClipboard() function.  If a NULL
  847.                 is passed, the clipboard support is not allowed.  Please
  848.                 supply this tag value.  Don't leave users without clipboard
  849.                 support.  It is recommended that the unit opened by
  850.                 OpenClipboard() be 0 or PRIMARY_UNIT, since that is the
  851.                 standard unit, but you can pick whatever unit you or your user
  852.                 wants.  This stream can be safely given to multiple objects.
  853.  
  854.                 Default for this tag is NULL.  Applicability is (I    ).
  855.  
  856.         TEXTFIELD_ClipStream2 (struct ClipboardHandle *) -- ClipStream2 is
  857.                 used for the undo features of the textfield class.  It is
  858.                 obtained from the iffparse.library OpenClipboard() function.
  859.                 You should probably use a clipboard unit other than 0 to avoid
  860.                 conflicts with normal clips.  This stream can be safely passed
  861.                 to multiple objects.  (See TEXTFIELD_UndoStream)
  862.  
  863.                 Default for this tag is NULL.  Applicability (I    ).
  864.  
  865.         TEXTFIELD_UndoStream -- This is a synonym for
  866.                 TEXTFIELD_ClipStream2.  See it above.
  867.  
  868.         TEXTFIELD_LineLength (ULONG *) -- Get the contents of the ULONG to a
  869.                 line number and that ULONG will be replaced with the length of
  870.                 that line in characters.  If you are worried about the line
  871.                 lengths changing while you are reading them, then try removing
  872.                 the gadget from the window first.  Please realize that if the
  873.                 gadget has a relative width or height then the lengths can
  874.                 change anytime the user resized the window.
  875.  
  876.                 Applicability is (  G  ). (V2)
  877.  
  878.         TEXTFIELD_SelectSize (ULONG/ULONG *) -- Set the number of characters
  879.                 to highlight starting from the current cursor position.  If
  880.                 the value is 0, highlighting will be turned off.  If the
  881.                 number is non-zero, that number of characters will be
  882.                 highlighted.  You can also get the number of highlighted
  883.                 characters with this attribute by passing a ULONG *.  If you
  884.                 get a 0 value, then highlighting is turned off.  This can is
  885.                 useful for the copy, cut, and paste commands.
  886.  
  887.                 Applicability is ( SG U). (V2)
  888.  
  889.         TEXTFIELD_Copy -- When this attribute is specified, the gadget copies
  890.                 any highlighted text to the clipboard.  Highlighting is turned
  891.                 off after issuing this.  You can put Copy in a menu with this.
  892.                 This does not take a parameter.
  893.  
  894.                 Applicability is ( S  U). (V2)
  895.  
  896.         TEXTFIELD_CopyAll -- When this attribute is specified, the gadget
  897.                 copies all of the gadget's text to the clipboard.  It does not
  898.                 affect the state of the highlight and the text does not need
  899.                 to be highlighted.  You can put Copy All in a menu with this.
  900.                 This does not take a parameter.
  901.  
  902.                 Applicability is ( S  U). (V2)
  903.  
  904.         TEXTFIELD_Cut -- When this attribute is specified, the gadget will
  905.                 cut any highlighted text to the clipboard.  Cut text goes to
  906.                 the clipboard.  You can put Cut in a menu with this.  This
  907.                 does not take a parameter.
  908.  
  909.                 Applicability is ( S  U). (V2)
  910.  
  911.         TEXTFIELD_Paste -- When this attribute is specified, the gadget will
  912.                 delete any highlighted text to the undo buffer, then it will
  913.                 paste the text from the clipboard to the gadget.  You can put
  914.                 Paste in a menu with this.  This does not take a parameter.
  915.  
  916.                 Applicability is ( S  U). (V2)
  917.  
  918.         TEXTFIELD_Erase -- When this attribute is specified, the gadget will
  919.                 delete any highlighted text, otherwise do nothing.  If text
  920.                 is deleted, it's placed in the undo buffer.  You can put Erase
  921.                 in a menu with this.  This does not take a parameter.
  922.  
  923.                 Applicability is ( S  U). (V2)
  924.  
  925.         TEXTFIELD_Undo -- When this attribute is specified, the gadget will
  926.                 delete any highlighted text, then insert the text from the
  927.                 undo buffer.  You can put Undo in a menu with this.  This does
  928.                 not take a parameter.
  929.  
  930.                 Applicability is ( S  U). (V2)
  931. textfield.gadget/Borders                             textfield.gadget/Borders
  932.  
  933.     BORDER REFERENCE
  934.         You can use the width and heights given when calculating window sizes
  935.         and limits.  To make the window's height minimal with respect to your
  936.         font, use (window border top) + (window border bottom) + (num_lines *
  937.         (font height)) + (gadget border height).  Also, if you use
  938.         TEXTFIELD_Spacing, you'll have to add that in too.
  939.  
  940.         TEXTFIELD_BORDER_NONE            Border takes up:  0 width,  0 height
  941.         TEXTFIELD_BORDER_BEVEL           Border takes up:  8 width,  4 height
  942.         TEXTFIELD_BORDER_DOUBLEBEVEL     Border takes up: 12 width,  6 height
  943. textfield.gadget/Alignment                         textfield.gadget/Alignment
  944.  
  945.     ALIGMENT REFERENCE
  946.         TEXTFIELD_ALIGN_LEFT             Cause text to be flush left
  947.         TEXTFIELD_ALIGN_CENTER           Cause text to be centered
  948.         TEXTFIELD_ALIGN_RIGHT            Cause text to be flush right
  949. textfield.gadget/Bugs                                   textfield.gadget/Bugs
  950.  
  951.     BUGS
  952.         What bugs?  Please let me know if you find any.
  953.         See the History file for a list of fixed bugs.
  954.  
  955.         DEBUGGING
  956.  
  957.         A version of the textfield.gadget library is provided with routines
  958.         that print debug information to the serial port using the current
  959.         settings for the serial device.  It could be helpful.  Just rename
  960.         the debug gadget (textfield.gadget.db) to textfield.gadget and
  961.         place it in the normal gadgets place listed above.
  962. textfield.gadget/Author                               textfield.gadget/Author
  963.  
  964.     AUTHOR
  965.         To contact me for reporting bugs or giving suggestions:
  966.  
  967.         Mark Thomas
  968.         9036 N. Lamar, Apt. #125
  969.         Austin, TX  78753
  970.  
  971.         or
  972.  
  973.         mthomas@zilker.net
  974. textfield.gadget/GetClass()                       textfield.gadget/GetClass()
  975.  
  976.     NAME
  977.         TEXTFIELD_GetClass -- Gets the pointer to the textfield class. (V1)
  978.  
  979.     SYNOPSIS
  980.         textfield_class = TEXTFIELD_GetClass();
  981.         D0
  982.  
  983.         Class *TEXTFIELD_GetClass(void);
  984.  
  985.     FUNCTION
  986.         Obtains the pointer to the textfield.gadget class for use with
  987.         NewObject().  This function always returns a valid pointer so
  988.         you do not need to check it.  The reason is that if the library
  989.         opens fine, then the pointer returned is already setup.  (Of course
  990.         this implies that if opening the library fails, you shouldn't be
  991.         calling this.)
  992.  
  993.     INPUTS
  994.         None.
  995.  
  996.     RESULT
  997.         textfield_class - the pointer to the textfield.gadget class.
  998.  
  999.     BUGS
  1000.         None.
  1001. textfield.gadget/GetCopyright()               textfield.gadget/GetCopyright()
  1002.  
  1003.     NAME
  1004.         TEXTFIELD_GetCopyright -- Gets a pointer to the copyright and version
  1005.                                   string for use in About requesters. (V3)
  1006.  
  1007.     SYNOPSIS
  1008.         copyright_str = TEXTFIELD_GetCopyright();
  1009.         D0
  1010.  
  1011.         char *TEXTFIELD_GetCopyright(void);
  1012.  
  1013.     FUNCTION
  1014.         Gets a pointer to a string that contains the copyright information
  1015.         for textfield.gadget.  The string has the following format:
  1016.  
  1017.         "textfield.gadget 3.1 is\nCopyright © 1995 Mark Thomas"
  1018.  
  1019.     INPUTS
  1020.         None.
  1021.  
  1022.     RESULT
  1023.         copyright_str - the pointer to the copyright string.
  1024.  
  1025.     BUGS
  1026.         None.
  1027.